package org.brakepedal.server.config;

import com.corundumstudio.socketio.SocketConfig;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.annotation.SpringAnnotationScanner;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.stereotype.Component;

import java.util.Random;
import java.util.TimeZone;


/**
 * Date: 2024/3/31 22:05
 *
 * @author Huanyu Mark
 */
@Configuration
//@EnableWebSocket
public class WebSocketConfig {

    @Lazy
    @Bean
    public TimeZone currentTimeZone(){
        return TimeZone.getTimeZone("Asia/Shanghai");
    }

    @Lazy
    @Bean
    public Random globalRandom(){
        return new Random();
    }

    @Bean
    @ConfigurationProperties("socket-io.socket-config")
    public SocketConfig socketConfig() {
        return new SocketConfig();
    }

    @Bean
    @ConfigurationProperties("socket-io.server-config")
    public com.corundumstudio.socketio.Configuration socketIOServerConfiguration(SocketConfig socketConfig) {
        com.corundumstudio.socketio.Configuration configuration = new com.corundumstudio.socketio.Configuration();
        configuration.setSocketConfig(socketConfig);
        return configuration;
    }

    @Bean
    public SocketIOServer socketIOServer(com.corundumstudio.socketio.Configuration configuration) {
        return new SocketIOServer(configuration);
    }

    /**
     * 注册socket-io 注解
     * 开启SocketIOServer注解支持，比如 @OnConnect、@OnEvent
     * @param socketServer socketIo 服务器
     */
    @Bean
    @DependsOn("socketIOServer")
    public SpringAnnotationScanner springAnnotationScanner(SocketIOServer socketServer) {
        return new SpringAnnotationScanner(socketServer);
    }

//    @Bean(value = "serverEndpointExporter")
//    public ServerEndpointExporter serverEndpointExporter() {
//        return new ServerEndpointExporter();
//    }

    @Slf4j
    @Component
    public static class SocketIOInitListener implements ApplicationListener<ApplicationReadyEvent> {
        private final SocketIOServer server;


        public SocketIOInitListener(SocketIOServer server) {
            this.server = server;
        }

        @Override
        public void onApplicationEvent(@NotNull ApplicationReadyEvent applicationReadyEvent) {

            server.start();
            log.info("--------------------------------------");
            log.info("socket.io启动成功: " + server.getConfiguration().getPort());
            log.info("--------------------------------------");
        }
    }

    @Slf4j
    @Component
    public static class SocketIOStopListener implements ApplicationListener<ContextClosedEvent> {
        private final SocketIOServer server;

        public SocketIOStopListener(SocketIOServer server) {
            this.server = server;
        }

        // 监听kill pid     无法监听 kill -9 pid
        @Override
        public void onApplicationEvent(@NotNull ContextClosedEvent contextClosedEvent) {
            server.stop();
            log.info("--------------------------------------");
            log.info("socket.io 关闭成功");
            log.info("--------------------------------------");
        }
    }
}
